#include "giza.h"
static CUProgress progress;


CUString find_align( CGiza &giza, char lang, int offset )
{
	if( lang == 'S' )	{
		return giza.align.align_list.GetAt( offset );
	}
	else if( lang == 'T' )	{
		for( int i=0; i<giza.align.align_list.GetSize(); i++ )	{
			CUString str = giza.align.align_list.GetAt(i);
			if( str.Count( " " ) >= 1 )	{
				fprintf( stderr, "warn! 1:n alignments are not supported now\n" );
				return "";
			}
			if( atoi( str.GetStr() ) == offset+1 )	{
				char buf[12];
				sprintf( buf, "%d", i );
				return buf;
			}
		}
//		return "not found";
	}

	return "";
}

bool get_token( CUString tok, int field, CUString &tok_str, CUString &tok_lemma, CUString &tok_pos )
{
	CUStringListSN tok_list( tok, "/" );
	if( field == 3 )	{
		if( tok_list.GetSize() == 3 )	{
			tok_str = tok_list.GetAt(0); tok_lemma = tok_list.GetAt(1); tok_pos = tok_list.GetAt(2);
			return true;
		}
		else {
			fprintf( stderr, "invalid token (not %d fields)\n", field );
			return false;
		}
	}
	else if( field == 2 )	{
		int idx = tok.ReverseFind('/');
		tok_str = tok.Left(idx); tok_lemma = ""; tok_pos = tok.Mid( idx+1 );
		return true;


	}
	else {
		fprintf( stderr, "invalid field number %d, (only 2 and 3 are supported)", field );
		return false;
	}

	return false;
}


bool func1( char giza_fn[], char lang[], int src_field, int tgt_field, char out_fn[] )
{
	CGiza giza;
	if( giza.Open( giza_fn ) == false )	return false;

	CUString lang_str = lang;
	lang_str.MakeToUpper();
	if( lang_str.GetLength() != 2 )	{
		fprintf( stderr, "invalid lang option; only 2 characters are required\n" );
		return 1;
	}
	char src = lang_str.GetAt(0);
	char tgt = lang_str.GetAt(1);

	CUTextFile out_file( out_fn, "w" );
	if( out_file.IsOpen() == false )	{
		fprintf( stderr, "fail to open file %s\n", out_fn );
		return 1;
	}


	// start
	int num_sent =0;
	while( 1 )	{
		if( giza.ReadSent() == false )	break;
		num_sent++;

		// src
		for( int i=1; i<giza.src.tok_list.GetSize(); i++ )	{
			CUString tok = giza.src.tok_list.GetAt(i);
			CUString tok_str, tok_lemma, tok_pos;

			if( get_token( tok, tgt_field, tok_str, tok_lemma, tok_pos ) == false )	{
				fprintf( stderr, "sent: %d\n", num_sent );
			}

			CUString align = find_align( giza, 'S', i );

			fprintf( out_file.GetFP(), "%d\t", i );	// TOK_OFFSET
			fprintf( out_file.GetFP(), "%d\t", num_sent ); // SNT_ID
			fprintf( out_file.GetFP(), "%c\t", src ); // LANG
			fprintf( out_file.GetFP(), "%s\t", align.GetStr() ); // ALN_OFFSET
			fprintf( out_file.GetFP(), "%s\t%s\t%s", tok_str.GetStr(), tok_lemma.GetStr(), tok_pos.GetStr() );
			fprintf( out_file.GetFP(), "\t" ); // TOK_EGL
			fprintf( out_file.GetFP(), "\t" ); // TOK_NC
			fprintf( out_file.GetFP(), "\t" ); // PROB
			fprintf( out_file.GetFP(), "1" ); // VALID
			fprintf( out_file.GetFP(), "\n" );
			fflush( out_file.GetFP() );

		}

		// tgt
		for( int i=0; i<giza.tgt.tok_list.GetSize(); i++ )	{
			CUString tok = giza.tgt.tok_list.GetAt(i);
			CUString tok_str, tok_lemma, tok_pos;
			if( get_token( tok, tgt_field, tok_str, tok_lemma, tok_pos ) == false )	{
				fprintf( stderr, "sent: %d\n", num_sent );
			}

			CUString align = find_align( giza, 'T', i );

			fprintf( out_file.GetFP(), "%d\t", i+1 );	// TOK_OFFSET
			fprintf( out_file.GetFP(), "%d\t", num_sent ); // SNT_ID
			fprintf( out_file.GetFP(), "%c\t", tgt ); // LANG
			fprintf( out_file.GetFP(), "%s\t", align.GetStr() ); // ALN_OFFSET
			fprintf( out_file.GetFP(), "%s\t%s\t%s", tok_str.GetStr(), tok_lemma.GetStr(), tok_pos.GetStr() );
			fprintf( out_file.GetFP(), "\t" ); // TOK_EGL
			fprintf( out_file.GetFP(), "\t" ); // TOK_NC
			fprintf( out_file.GetFP(), "\t" ); // PROB
			fprintf( out_file.GetFP(), "1" ); // VALID
			fprintf( out_file.GetFP(), "\n" );
			fflush( out_file.GetFP() );

		}

	}

	fprintf( stderr, "%d sent converted\n", num_sent );

	return true;	
}


int main( int argc, char *argv[] )
{
	if( argc != 6 )	{
		fprintf( stderr, "desc:  convert a giza result files into column-seperated data file\n" );
		fprintf( stderr, "usage: %s GIZA lang #src-field #tgt-field out-file\n", argv[0] );
		fprintf( stderr, "ex:    %s wa.giza EK 2 2 wa.dbdata\n", argv[0] );
		return 1;
	}


	if( func1( argv[1], argv[2], atoi( argv[3] ), atoi( argv[4] ), argv[5] ) == false )	{
		return 1;
	}

	return 0;
}

